package com.runner.player.state;

import com.badlogic.gdx.math.MathUtils;
import com.runner.entity.CollisionEntity;
import com.runner.observer.Event;
import com.runner.player.Player;

public class DoubleJumpState extends PlayerState {

	private boolean hitGround;
	private boolean peaked;
	private boolean requestRoll;
	private float jumpTimer;
	private float angle;
	private float startAngle;
	private float endAngle;
	private float timer;

	public static float SPIN_TIME = 0.5f;

	public DoubleJumpState(Player p) {
		super(p);
		peaked = false;
	}

	@Override
	public void update(float delta) {
		if (hitGround) {
			// if the player hit the roll button, roll immediately after hitting
			// the ground
			if (!requestRoll) {
				player.changeState(new NormalState(player));
			} else {
				player.changeState(new RollState(player));
			}
			exit();
		}
		jumpTimer += delta;
		if (!peaked && jumpTimer < player.getJumpTimer()) {
			player.getPhysics().getBody().setLinearVelocity(player.getJumpVelocity().scl(delta));
		}

		if (!peaked) {
			if (player.getPhysics().getBody().getLinearVelocity().y < 0) {
				player.getPhysics().getBody().setGravityScale(Player.JUMP_GRAVITY_PEAKED_SCALE);
				peaked = true;
			}
		}

		if (timer <= SPIN_TIME) {
			angle = startAngle - (timer / SPIN_TIME * (startAngle - endAngle));
			player.setDirection(angle * MathUtils.radiansToDegrees);
			timer += delta;
		}

	}

	@Override
	public void newAction(INPUT input) {
		switch (input) {
		case TOUCH_UP:
			player.getPhysics().getBody().setGravityScale(2);
			if (!peaked) {
				// player.getPhysics().getBody().setLinearVelocity(0,0);
				peaked = true;
			}
			break;
		case ROLL:
			if (peaked) {
				requestRoll = true;
			}
			break;
		case DIVE:
			exit();
			player.changeState(new AirDiveState(player));
			break;
		default:
			break;

		}
	}

	@Override
	public void enter() {
		jumpTimer = 0;
		hitGround = false;
		requestRoll = false;
		peaked = false;
		player.getSubject().notify(Event.EVENT_DOUBLE_JUMP);
		player.getPhysics().getBody().setGravityScale(player.getJumpGravityScale());
		player.getPhysics().getBody().setLinearVelocity(player.getJumpVelocity());

		timer = 0;
		startAngle = 0f;
		endAngle = 6.28f;
	}

	@Override
	public void exit() {
		player.getPhysics().getBody().setGravityScale(1);
	}

	@Override
	public void collide(CollisionEntity otherBody) {
		if (otherBody.getPhysics().getType().equals(TYPE.GROUND)) {
			hitGround = true;
			player.getSubject().notify(Event.EVENT_PLAYER_HIT_GROUND);
		}

	}

}
